<?php

namespace App\Admin\Service\Base;

use App\Common\Exception\ApiMessageException;
use App\Common\Interfaces\AdminLoginServiceInterface;
use App\Common\Model\Model;
use App\Common\Util\AdminAuth;
use App\Common\Util\TP;

/**
 * 登录账号服务
 *
 * Class LoginAccountService
 */
class LoginAccountService
{
    const CURRENT_ACCOUNT_CACHE_KEY = "gotoAccount:Current";

    /**
     * @param string $sign
     * @param bool   $isStrict
     *
     * @return AdminLoginServiceInterface
     * @throws \Exception
     */
    public static function getLoginService(string $sign, bool $isStrict = false): AdminLoginServiceInterface
    {
        $loginMap = TP::config('admin_login');

        $classname = $loginMap[$sign] ?? null;
        if (!$classname && $isStrict) {
            throw new \Exception("登录失败！");
        }

        $classname = $classname ?: $loginMap[''];
        $class     = new $classname();

        if (!$class instanceof AdminLoginServiceInterface) {
            throw new \Exception(sprintf("%s登录未实现 %s 接口", $classname, AdminLoginServiceInterface::class));
        }

        return $class;
    }

    /**
     * 前往账号
     *
     * @param Model $model
     *
     * @return void
     * @throws ApiMessageException
     */
    public static function gotoAccount(Model $model): void
    {
        if (!self::isNormalLogin()) {
            throw new ApiMessageException("当前已经是登入状态，不可登入");
        }
        $currentAccountCacheKey = self::CURRENT_ACCOUNT_CACHE_KEY;

        $currentAccount = AdminAuth::getInfo();
        TP::session()->set($currentAccountCacheKey, $currentAccount);

        AdminAuth::save($model);
        op_log(
            des:sprintf("%s 登入账号 %s, 新账号模型：%s", $currentAccount->name ?: '--', $model->name ?: '--', $model::class),
        );
    }

    /**
     * 退出账号
     *
     * @return void
     */
    public static function quitAccount(): void
    {
        $currentAccountCacheKey = self::CURRENT_ACCOUNT_CACHE_KEY;

        $currentAccount = TP::session()->get($currentAccountCacheKey);
        if ($currentAccount) {
            TP::session()->delete($currentAccountCacheKey);
            $loginAccount = AdminAuth::getInfo();
            AdminAuth::save($currentAccount);
            op_log(
                des:sprintf("%s 登出账号 %s, 账号模型：%s", $currentAccount->name ?: '--', $loginAccount->name ?: '--', $loginAccount::class),
            );
        }
    }

    /**
     * 是否正常登录
     *
     * @return bool
     */
    public static function isNormalLogin(): bool
    {
        return empty(TP::session()->get(self::CURRENT_ACCOUNT_CACHE_KEY));
    }
}